package com.feidian.helper.provider;

import java.util.HashMap;
import java.util.List;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.provider.BaseColumns;
import android.text.TextUtils;
import android.util.Log;

public class ZkgjProvider extends ContentProvider {
	private static final String TAG = "ZkgjProvider";

	public static final String AUTHORITY = "com.feidian.com";

	private static final int DEGREETYPES = 1;
	private static final int DEGREETYPES_ID = 2;
	private static final int CATEGORY = 3;
	private static final int CATEGORY_ID = 4;
	private static final int COLLEGE = 5;
	private static final int COLLEGE_ID = 6;
	private static final int PROFESSION = 7;
	private static final int PROFESSION_ID = 8;
	private static final int COLLEGE_PROFESSION = 9;
	private static final int COLLEGE_PROFESSION_ID = 10;
	

	// Uri matcher to decode incoming URIs
	private final UriMatcher sUriMatcher;

	// A projection map used to select columns from the database
	private HashMap<String, String> sDegreeTypeProjectionMap;
	private HashMap<String, String> sCategoryProjectionMap;
	private HashMap<String, String> sCollegeProjectionMap;
	private HashMap<String, String> sProfessionProjectionMap;
//	private HashMap<String, String> sCollegeProfessionProjectionMap;

	private ZkgjDatabaseHelper dbHelper = null;

	/**
	 * global provider initialization
	 */
	public ZkgjProvider() {

		sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);

		sUriMatcher.addURI(AUTHORITY, DegreeType.TABLE_NAME, DEGREETYPES);
		sUriMatcher.addURI(AUTHORITY, DegreeType.TABLE_NAME + "/#",
				DEGREETYPES_ID);
		
		sUriMatcher.addURI(AUTHORITY, Category.TABLE_NAME, CATEGORY);
		sUriMatcher.addURI(AUTHORITY, Category.TABLE_NAME + "/#", CATEGORY_ID);
		
		sUriMatcher.addURI(AUTHORITY, College.TABLE_NAME, COLLEGE);
		sUriMatcher.addURI(AUTHORITY, College.TABLE_NAME + "/#", COLLEGE_ID);
		
		sUriMatcher.addURI(AUTHORITY, Profession.TABLE_NAME, PROFESSION);
		sUriMatcher.addURI(AUTHORITY, Profession.TABLE_NAME + "/#",
				PROFESSION_ID);
		
		sUriMatcher.addURI(AUTHORITY, CollegeProfession.TABLE_NAME, COLLEGE_PROFESSION);
		sUriMatcher.addURI(AUTHORITY, CollegeProfession.TABLE_NAME + "/#",
				COLLEGE_PROFESSION_ID);
		
		sDegreeTypeProjectionMap = new HashMap<String, String>();
		sDegreeTypeProjectionMap.put(DegreeType._ID, DegreeType._ID);
		sDegreeTypeProjectionMap.put(DegreeType.TYPE, DegreeType.TYPE);
		sDegreeTypeProjectionMap.put(DegreeType.NAME, DegreeType.NAME);
		
		sCategoryProjectionMap = new HashMap<String, String>();
		sCategoryProjectionMap.put(Category._ID, Category._ID);
		sCategoryProjectionMap.put(Category.CODE, Category.CODE);
		sCategoryProjectionMap.put(Category.NAME, Category.NAME);
		
		sCollegeProjectionMap = new HashMap<String, String>();
		sCollegeProjectionMap.put(College._ID, College._ID);
		sCollegeProjectionMap.put(College.CODE, College.CODE);
		sCollegeProjectionMap.put(College.NAME, College.NAME);
		
		sProfessionProjectionMap = new HashMap<String, String>();
		sProfessionProjectionMap.put(Profession._ID, Profession._ID);
		sProfessionProjectionMap.put(Profession.CODE, Profession.CODE);
		sProfessionProjectionMap.put(Profession.NAME, Profession.NAME);
		sProfessionProjectionMap.put(Profession.CATEGORY, Profession.CATEGORY);
		sProfessionProjectionMap.put(Profession.DEGREE_TYPE, Profession.DEGREE_TYPE);

//		sCollegeProfessionProjectionMap = new HashMap<String, String>();
//		sCollegeProfessionProjectionMap.put(Profession.TABLE_NAME + "."
//				+ Profession._ID, Profession.TABLE_NAME + "." + Profession._ID
//				+ " AS id");
//		sCollegeProfessionProjectionMap.put(CollegeProfession.TABLE_NAME + "."
//				+ CollegeProfession._ID, CollegeProfession.TABLE_NAME + "."
//				+ CollegeProfession._ID + " AS _id");
//		sCollegeProfessionProjectionMap.put(CollegeProfession.COLLEGE,
//				CollegeProfession.COLLEGE);
//		sCollegeProfessionProjectionMap.put(CollegeProfession.PROFESSION,
//				CollegeProfession.PROFESSION);
//		sCollegeProfessionProjectionMap.put(Profession.NAME, Profession.NAME);
//		sCollegeProfessionProjectionMap.put(Profession.DEGREE_TYPE,
//				Profession.DEGREE_TYPE);
	}

	@Override
	public boolean onCreate() {
		dbHelper = new ZkgjDatabaseHelper(getContext());
		return true;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
		switch (sUriMatcher.match(uri)) {
		case DEGREETYPES:
			qb.setTables(DegreeType.TABLE_NAME);
			qb.setProjectionMap(sDegreeTypeProjectionMap);
			break;
		case DEGREETYPES_ID:
			qb.setTables(DegreeType.TABLE_NAME);
			qb.setProjectionMap(sDegreeTypeProjectionMap);
			qb.appendWhere(DegreeType._ID + "=?");
			selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
					new String[] { uri.getLastPathSegment() });
			break;
		case CATEGORY:
			qb.setTables(Category.TABLE_NAME);
			qb.setProjectionMap(sCategoryProjectionMap);
			break;
		case CATEGORY_ID:
			qb.setTables(Category.TABLE_NAME);
			qb.setProjectionMap(sCategoryProjectionMap);
			qb.appendWhere(Category._ID + "=?");
			selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
					new String[] { uri.getLastPathSegment() });
			break;
		case COLLEGE:
			qb.setTables(College.TABLE_NAME);
			qb.setProjectionMap(sCollegeProjectionMap);
			break;
		case COLLEGE_ID:
			qb.setTables(College.TABLE_NAME);
			qb.setProjectionMap(sCollegeProjectionMap);
			qb.appendWhere(College._ID + "=?");
			selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
					new String[] { uri.getLastPathSegment() });
			break;
		case PROFESSION:
			qb.setTables(Profession.TABLE_NAME);
			qb.setProjectionMap(sProfessionProjectionMap);
			break;
		case PROFESSION_ID:
			qb.setTables(Profession.TABLE_NAME);
			qb.setProjectionMap(sProfessionProjectionMap);
			qb.appendWhere(Profession._ID + "=?");
			selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
					new String[] { uri.getLastPathSegment() });
			break;
		case COLLEGE_PROFESSION:
			qb.setTables(CollegeProfession.TABLE_NAME + " LEFT OUTER JOIN "
					+ College.TABLE_NAME + " ON "
					+ CollegeProfession.TABLE_NAME + "."
					+ CollegeProfession.COLLEGE + " = " + College.TABLE_NAME
					+ "." + College.CODE + " LEFT OUTER JOIN "
					+ Profession.TABLE_NAME + " ON "
					+ CollegeProfession.TABLE_NAME + "."
					+ CollegeProfession.PROFESSION + " = "
					+ Profession.TABLE_NAME + "." + Profession.CODE);
//			qb.setProjectionMap(sCollegeProfessionProjectionMap);
			break;
		case COLLEGE_PROFESSION_ID:
			qb.setTables(CollegeProfession.TABLE_NAME + " LEFT OUTER JOIN "
					+ College.TABLE_NAME + " ON "
					+ CollegeProfession.TABLE_NAME + "."
					+ CollegeProfession.COLLEGE + " = " + College.TABLE_NAME
					+ "." + College.CODE + " LEFT OUTER JOIN "
					+ Profession.TABLE_NAME + " ON "
					+ CollegeProfession.TABLE_NAME + "."
					+ CollegeProfession.PROFESSION + " = "
					+ Profession.TABLE_NAME + "." + Profession.CODE);
//			qb.setProjectionMap(sCollegeProfessionProjectionMap);
			qb.appendWhere(CollegeProfession.TABLE_NAME + "."
					+ CollegeProfession.COLLEGE + "=? ");
			qb.appendWhere(" AND ");
			qb.appendWhere(Profession.TABLE_NAME + "." + Profession.DEGREE_TYPE
					+ "=?");
			List<String> argsList = uri.getPathSegments();
			String[] argsArray = new String[argsList.size()];
			argsList.toArray(argsArray);
			selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
					argsArray);
			break;
		default:
			throw new IllegalArgumentException("Unknown URI " + uri);
		}
		String orderBy;
		if (TextUtils.isEmpty(sortOrder)) {
			orderBy = " _id DESC";
		} else {
			orderBy = sortOrder;
		}
		Log.d(TAG,
				"sql clause is ---"
						+ qb.buildQuery(null, null, null, null, null, null)
						+ "---");
		SQLiteDatabase db = dbHelper.getReadableDatabase();
		Cursor c = qb.query(db, projection, selection, selectionArgs, null,
				null, orderBy);
		c.setNotificationUri(getContext().getContentResolver(), uri);
		int count = c.getCount();
		Log.d(TAG, "the record count is + " + count);
		return c;
	}

	@Override
	public String getType(Uri uri) {
		switch (sUriMatcher.match(uri)) {
		case DEGREETYPES:
			return "vnd.android.cursor.dir/degree_types";
		case DEGREETYPES_ID:
			return "vnd.android.cursor.item/degree_types";
		default:
			throw new IllegalArgumentException("this is unkown uri:" + uri);
		}
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		SQLiteDatabase db = dbHelper.getWritableDatabase();

		switch (sUriMatcher.match(uri)) {
		case DEGREETYPES:
			long rowId = db.insert(DegreeType.TABLE_NAME, null, values);

			// If the insert succeeded, the row ID exists.
			if (rowId > 0) {
				Uri noteUri = ContentUris.withAppendedId(
						DegreeType.CONTENT_ID_URI_BASE, rowId);
				getContext().getContentResolver().notifyChange(noteUri, null);
				return noteUri;
			}
		default:
			throw new SQLException("Failed to insert row into " + uri);
		}

	}

	@Override
	public int bulkInsert(Uri uri, ContentValues[] values) {
		switch (sUriMatcher.match(uri)) {
		case DEGREETYPES:
			SQLiteDatabase db = dbHelper.getWritableDatabase();
			db.beginTransaction();
			try {
				int count = values.length;
				for (int i = 0; i < count; i++) {
					if (db.insert(DegreeType.TABLE_NAME, null, values[i]) < 0) {
						return 0;
					}
				}
				db.setTransactionSuccessful();
			} finally {
				db.endTransaction();
			}
			getContext().getContentResolver().notifyChange(uri, null);
			return values.length;
		default:
			throw new SQLException("Failed to buldk insert row into " + uri);
		}

	}

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		SQLiteDatabase db = dbHelper.getWritableDatabase();
		String finalWhere;

		int count;
		switch (sUriMatcher.match(uri)) {
		case DEGREETYPES:
			count = db.delete(DegreeType.TABLE_NAME, selection, selectionArgs);
			break;
		case DEGREETYPES_ID:
			finalWhere = DatabaseUtils.concatenateWhere(DegreeType._ID + "="
					+ ContentUris.parseId(uri), selection);
			count = db.delete(DegreeType.TABLE_NAME, finalWhere, selectionArgs);
			break;
		default:
			throw new IllegalArgumentException("Unknown URI " + uri);

		}
		getContext().getContentResolver().notifyChange(uri, null);
		return count;
	}

	@Override
	public int update(Uri uri, ContentValues values, String where,
			String[] whereArgs) {
		SQLiteDatabase db = dbHelper.getWritableDatabase();
		int count;
		String finalWhere;

		switch (sUriMatcher.match(uri)) {
		case DEGREETYPES:
			// If URI is main table, update uses incoming where clause and args.
			count = db.update(DegreeType.TABLE_NAME, values, where, whereArgs);
			break;

		case DEGREETYPES_ID:
			// If URI is for a particular row ID, update is based on incoming
			// data but modified to restrict to the given ID.
			finalWhere = DatabaseUtils.concatenateWhere(DegreeType._ID + " = "
					+ ContentUris.parseId(uri), where);
			count = db.update(DegreeType.TABLE_NAME, values, finalWhere,
					whereArgs);
			break;

		default:
			throw new IllegalArgumentException("Unknown URI " + uri);
		}

		getContext().getContentResolver().notifyChange(uri, null);

		return count;
	}

	public static final class DegreeType implements BaseColumns {
		private DegreeType() {
		}

		public static final String TABLE_NAME = "degree_types";

		public static final Uri CONTENT_URI = Uri.parse("content://"
				+ AUTHORITY + "/" + TABLE_NAME);

		public static final Uri CONTENT_ID_URI_BASE = Uri.parse("content://"
				+ AUTHORITY + "/" + TABLE_NAME + "/");

		public static final String TYPE = "type";
		public static final String NAME = "name";
	}

	public static final class Category implements BaseColumns {
		private Category() {
		}

		public static final String TABLE_NAME = "categories";

		public static final Uri CONTENT_URI = Uri.parse("content://"
				+ AUTHORITY + "/" + TABLE_NAME);

		public static final Uri CONTENT_ID_URI_BASE = Uri.parse("content://"
				+ AUTHORITY + "/" + TABLE_NAME + "/");

		public static final String CODE = "code";
		public static final String NAME = "name";
	}

	public static final class College implements BaseColumns {
		private College() {
		}

		public static final String TABLE_NAME = "colleges";

		public static final Uri CONTENT_URI = Uri.parse("content://"
				+ AUTHORITY + "/" + TABLE_NAME);

		public static final Uri CONTENT_ID_URI_BASE = Uri.parse("content://"
				+ AUTHORITY + "/" + TABLE_NAME + "/");

		public static final String CODE = "code";
		public static final String NAME = "name";
	}

	public static final class Profession implements BaseColumns {
		private Profession() {
		}

		public static final String TABLE_NAME = "professions";

		public static final Uri CONTENT_URI = Uri.parse("content://"
				+ AUTHORITY + "/" + TABLE_NAME);

		public static final Uri CONTENT_ID_URI_BASE = Uri.parse("content://"
				+ AUTHORITY + "/" + TABLE_NAME + "/");

		public static final String CODE = "code";
		public static final String NAME = "name";
		public static final String CATEGORY = "category";
		public static final String DEGREE_TYPE = "degree_type";
	}

	public static final class CollegeProfession implements BaseColumns {
		private CollegeProfession() {
		}

		public static final String TABLE_NAME = "college_professions";

		public static final Uri CONTENT_URI = Uri.parse("content://"
				+ AUTHORITY + "/" + TABLE_NAME);

		public static final Uri CONTENT_ID_URI_BASE = Uri.parse("content://"
				+ AUTHORITY + "/" + TABLE_NAME + "/");

		public static final String COLLEGE = "college";
		public static final String PROFESSION = "profession";
	}

}
